package com.mentalhealthplatform.utils.decryptUtils.field;

import com.mentalhealthplatform.utils.decryptUtils.DecryptionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Collection;

@Component
public class DecryptFieldProcessor {

    // 初始化日志记录器
    private static final Logger logger = LoggerFactory.getLogger(DecryptFieldProcessor.class);

    @Value("${decrypt.secret.key}")
    private String secretKey;

    /**
     * 解密对象中带有 @Decrypt 注解的字段
     *
     * @param dto 需要解密的对象
     * @throws DecryptionException 解密异常
     */
    public void decryptFields(Object dto) throws DecryptionException {
        if (dto == null) {
            return;
        }

        Field[] fields = dto.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Decrypt.class)) {
                field.setAccessible(true);
                try {
                    Object encryptedValue = field.get(dto);
                    if (encryptedValue != null && encryptedValue instanceof String) {
                        String encryptedStr = (String) encryptedValue;
                        logger.debug("Decrypting field {} with value {}", field.getName(), encryptedStr);
                        String decryptedValue = AESUtils.decrypt(encryptedStr, secretKey);
                        field.set(dto, decryptedValue);
                        logger.debug("Decrypted field {} to {}", field.getName(), decryptedValue);
                    }
                } catch (Exception e) {
                    logger.error("Error decrypting field {}: {}. Exception: {}", field.getName(), field.getType().getName(), e.getMessage(), e);
                }
            }

            // 递归处理嵌套对象
            try {
                Object nestedObject = field.get(dto);
                if (nestedObject != null && !isPrimitiveOrWrapper(nestedObject.getClass())) {
                    logger.debug("Recursively decrypting nested field {}", field.getName());
                    decryptFields(nestedObject);
                }
            } catch (IllegalAccessException e) {
                logger.error("Error accessing nested field {}: {}", field.getName(), e.getMessage(), e);
            }

            // 处理集合中的对象
            if (Collection.class.isAssignableFrom(field.getType())) {
                try {
                    Collection<?> collection = (Collection<?>) field.get(dto);
                    if (collection != null) {
                        for (Object item : collection) {
                            decryptFields(item);
                        }
                    }
                } catch (Exception e) {
                    logger.error("Error processing collection field {}: {}", field.getName(), e.getMessage(), e);
                }
            }
        }
    }



    /**
     * 判断是否为基本类型或其包装类
     *
     * @param type 类类型
     * @return 是否为基本类型
     */
    private boolean isPrimitiveOrWrapper(Class<?> type) {
        return type.isPrimitive() ||
                type.equals(String.class) ||
                type.equals(Boolean.class) ||
                type.equals(Integer.class) ||
                type.equals(Long.class) ||
                type.equals(Double.class) ||
                type.equals(Float.class) ||
                type.equals(Byte.class) ||
                type.equals(Character.class) ||
                type.equals(Short.class);
    }
}
